home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / idioms.lha / idioms / 5-8.c < prev    next >
C/C++ Source or Header  |  1993-08-08  |  5KB  |  180 lines

  1. /* Copyright (c) 1992 by AT&T Bell Laboratories. */
  2. /* Advanced C++ Programming Styles and Idioms */
  3. /* James O. Coplien */
  4. /* All rights reserved. */
  5.  
  6. #include <iostream.h>
  7. #include <stdio.h>
  8.  
  9. struct BaseConstructor { BaseConstructor(int=0) { } };
  10.  
  11. class Number {
  12. public:
  13.     Number(BaseConstructor);
  14.     Number();
  15.     Number(double d);
  16.     Number(double rpart, double ipart);
  17.     Number operator=(Number & n) {
  18.     printf("Number::operator=(Number&)\n");
  19.         n.rep->referenceCount++;
  20.         if (--rep->referenceCount == 0) delete rep;
  21.         rep = n.rep;
  22.         return *this;
  23.     }
  24.     void redefine(Number *n) {
  25.     printf("Number::redefine(Number*)\n");
  26.         if (--rep->referenceCount == 0) delete rep;
  27.         rep = n;
  28.     }
  29.     Number(Number & n) {
  30.     printf("Number::Number(Number&)\n");
  31.         n.rep->referenceCount++;
  32.         rep = n.rep;
  33.     referenceCount = 1;
  34.     }
  35.     virtual ostream& operator<<(ostream &s) {
  36.     printf("Number::operator<<(ostream&)\n");
  37.         return rep->operator<<(s);
  38.     }
  39.     virtual Number operator+(Number &n) {
  40.     printf("Number::operator+(Number&)\n");
  41.         return rep->operator+(n);
  42.     }
  43.     virtual Number complexAdd(Number &n) {
  44.     printf("Number::complexAdd(Number&)\n");
  45.         return rep->complexAdd(n);
  46.     }
  47.     virtual Number doubleAdd(Number &n) {
  48.     printf("Number::doubleAdd(Number&)\n");
  49.         return rep->doubleAdd(n);
  50.     }
  51. private:
  52.     
  53.         Number *rep;
  54.         short referenceCount;
  55.     
  56. };
  57.  
  58. class Complex: public Number {
  59. friend class RealNumber;
  60. public:
  61.     Complex(double d, double e): Number(BaseConstructor()) {
  62.     printf("Complex::Complex(double, double)\n");
  63.         rpart = d; ipart = e;
  64.     }
  65.     Complex(const Complex& c): rpart(c.rpart), ipart(c.ipart), Number(BaseConstructor()) { }
  66.     Number operator+(Number &num) {
  67.     printf("Complex::operator+(Number&)\n");
  68.         Number n = num.complexAdd(*this);
  69.         return n;
  70.     }
  71.     Number complexAdd(Number &n);
  72.     Number doubleAdd(Number &n);
  73.     ostream& operator<<(ostream& o) {
  74.         o << "Complex(" << rpart << "," << ipart << ")";
  75.         return o;
  76.     }
  77. private:
  78.     double rpart, ipart;
  79. };
  80.  
  81. class RealNumber: public Number {
  82. friend Complex;
  83. public:
  84.     RealNumber(double d): Number(BaseConstructor()) {
  85.     printf("RealNumber::RealNumber(double)\n");
  86.         r = d;
  87.     }
  88.     RealNumber(const RealNumber& n): r(n.r), Number(BaseConstructor()) { } /******/
  89.     Number operator+(Number &num) {
  90.     printf("RealNumber::operator+(Number&)\n");
  91.         Number newnum = num.doubleAdd(*this);
  92.         return newnum;
  93.     }
  94.     Number complexAdd(Number &n);
  95.     Number doubleAdd(Number &n) {
  96.     printf("RealNumber::doubleAdd(Number&)\n");
  97.         Number retval;
  98.         RealNumber *c1 = new RealNumber(*this);
  99.         RealNumber *c2 = (RealNumber*)&n;
  100.         c1->r += c2->r;
  101.         retval.redefine(c1);
  102.         return retval;
  103.     }
  104.     ostream& operator<<(ostream& o) {
  105.     printf("RealNumber::operator<<(ostream&)\n");
  106.         o << "Float(" << r << ")";
  107.         return o;
  108.     }
  109. private:
  110.     double r;
  111. };
  112.  
  113. ostream& operator<<(ostream&o, Number n) {
  114.     Number *np = &n;
  115.     return np->operator<<(o);
  116. }
  117.  
  118. Number::Number(BaseConstructor) {
  119.     printf("Number::Number(BaseConstructor)\n");
  120.     referenceCount = 1;
  121. }
  122.  
  123. Number::Number() {
  124.     printf("Number::Number()\n");
  125.     rep = new RealNumber(0.0);
  126.     referenceCount = 1;
  127. }
  128.  
  129. Number::Number(double d) {
  130.     printf("Number::Number(double)\n");
  131.     rep = new RealNumber(d);
  132.     referenceCount = 1;
  133. }
  134.  
  135. Number::Number(double d, double e) {
  136.     printf("Number::Number(double,double)\n");
  137.     rep = new Complex(d, e);
  138.     referenceCount = 1;
  139. }
  140.  
  141. Number Complex::complexAdd(Number &n) {
  142.     printf("Number::complexAdd(Number&)\n");
  143.     Number retval;
  144.     Complex *c1 = new Complex(*this);
  145.     Complex *c2 = (Complex*)&n;
  146.     c1->rpart += c2->rpart;
  147.     c1->ipart += c2->ipart;
  148.     retval.redefine(c1);
  149.     return retval;
  150. }
  151.  
  152. Number Complex::doubleAdd(Number &n) {
  153.     printf("Complex::doubleAdd(Number&)\n");
  154.     Number retval;
  155.     Complex *c1 = new Complex(*this);
  156.     RealNumber *c2 = (RealNumber*)&n;
  157.     c1->rpart += c2->r;
  158.     retval.redefine(c1);
  159.     return retval;
  160. }
  161.  
  162. Number RealNumber::complexAdd(Number &n) {
  163.     printf("RealNumber::complexAdd(Number&)\n");
  164.     Number retval;
  165.     Complex *c1 = new Complex(r, 0);
  166.     Complex *c2 = (Complex*)&n;
  167.     c1->rpart += c2->rpart;
  168.     c1->ipart += c2->ipart;
  169.     retval.redefine(c1);
  170.     return retval;
  171. }
  172.  
  173. int main() {
  174.     Number a = Number(1.0, 1.0);
  175.     Number b = 2.0;
  176.     Number c = a + b;
  177.     Number d = c + a;  // added this one line and example bombs
  178.     cout << "a = " << a << ", b = " << b << ", c = " << c << "\n";
  179. }
  180.